﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace Obsidian.Tools
{
    public class Utils
    {
        #region 获取用户目录,通过用户ID计算目录
        /// <summary>
        /// 获取用户目录,通过用户ID计算目录
        /// </summary>
        /// <param name="uid">用户ID</param>
        /// <returns>返回计算出来的目录</returns>
        public static string GetUserDirectory(int uid)
        {
            int n = uid;
            StringBuilder sbDirectory = new StringBuilder(string.Format("http://users.st001.com/{0:X}/", n % 255));
            n = n / 255;
            sbDirectory.Append(string.Format("{0:X}/", n % 255));
            n = n / 255;
            sbDirectory.Append(string.Format("{0:X}/", n % 255));
            sbDirectory.Append(string.Format("{0}/", uid));

            return sbDirectory.ToString();
        }
        #endregion

        #region 获得当前绝对路径
        /// <summary>
        /// 获得当前绝对路径
        /// </summary>
        public static string GetMapPath(string strPath)
        {
            if (HttpContext.Current != null)
            {
                return HttpContext.Current.Server.MapPath(strPath);
            }
            else //非web程序引用
            {
                strPath = strPath.Replace("/", "\\");
                return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath.TrimStart('\\'));
            }
        }
        #endregion

        #region 获取用户ticket
        public static string GetTicket()
        {
            return GetCookies("ticket");
        }
        #endregion

        #region MD5加密
        public static string EncryptMD5(string text)
        {
            text = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(text, "MD5").ToLower();
            return text;
        }

        /// <summary>
        /// 签名字符串
        /// </summary>
        /// <param name="prestr">需要签名的字符串</param>
        /// <param name="key">密钥</param>
        /// <returns>签名结果</returns>
        public static string YSApiMd5Sign(string prestr, string key)
        {
            StringBuilder sb = new StringBuilder(32);
            prestr = prestr + key;
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] t =
          md5.ComputeHash(Encoding.UTF8.GetBytes(prestr));
            for (int i = 0; i < t.Length; i++)
            {
                sb.Append(t[i].ToString("x").PadLeft(2, '0'));
            }
            return sb.ToString();
        }
        #endregion

        #region 截取字符串
        /// <summary>
        /// 截取字符串(区分中英文)
        /// </summary>
        /// <param name="strContent">要截取的字符串</param>
        /// <param name="len">以英文长度</param>
        /// <param name="repStr">用来代替的字符，可为空</param>
        /// <returns></returns>
        public static string Substring(string strContent, int len, string repStr)
        {
            if (string.IsNullOrEmpty(strContent))
                return "";
            int i = 0;
            int sLen = strContent.Length;
            while (len > 0 && i < sLen)
            {
                if (strContent[i] > 255)
                {
                    len--;
                }
                len--;
                i++;
            }
            return i >= sLen ? strContent : strContent.Substring(0, i) + repStr;

        }
        /// <summary>
        /// 截取字符串(不区分中英文)
        /// </summary>
        /// <param name="strContent"></param>
        /// <param name="len"></param>
        /// /// <param name="repStr">用来代替的字符，可为空</param>
        /// <returns></returns>
        public static string Substr(string strContent, int len, string repStr)
        {
            return (strContent.Length > len ? strContent.Substring(0, len) : strContent) + repStr;
        }
        #endregion

        #region 获取web.config 里 appSettings 的值
        /// <summary>
        /// 获取web.config 里 appSettings 的值
        /// </summary>
        public static string GetAppSettingsValue(string asName)
        {
            if (ConfigurationManager.AppSettings[asName] != null)
            {
                return ConfigurationManager.AppSettings[asName].ToString();
            }
            return "";
        }
        #endregion

        #region 数据类型转换
        /// <summary>
        /// 将对象转换为String类型
        /// </summary>
        public static string ObjToStr(object expression, string defValue)
        {
            return TypeParse.ObjToStr(expression, defValue);
        }

        /// <summary>
        /// 将对象转换为Int32类型
        /// </summary>
        public static int StrToInt(object expression, int defValue)
        {
            return TypeParse.StrToInt(expression, defValue);
        }
        /// <summary>
        /// 将对象转换为Int32类型
        /// </summary>
        public static long StrToLong(object expression, long defValue)
        {
            return TypeParse.StrToLong(expression, defValue);
        }

        /// <summary>
        /// 将对象转换为float型
        /// </summary>
        public static float StrToFloat(object expression, float defValue)
        {
            return TypeParse.StrToFloat(expression, defValue);
        }

        /// <summary>
        /// 将对象转换为DateTime
        /// </summary>
        public static DateTime StrToDateTime(object expression, DateTime defValue)
        {
            return TypeParse.StrToDateTime(expression, defValue);
        }

        /// <summary>
        /// 将对象转换为decimal
        /// </summary>
        public static decimal StrToDecimal(object expression, decimal defValue)
        {
            return TypeParse.StrToDecimal(expression, defValue);
        }

        /// <summary>
        /// 将对象转换为Bool,[1或true为true,0或false为false]
        /// </summary>
        public static bool StrToBool(object expression, bool defValue)
        {
            return TypeParse.StrToBool(expression, defValue);
        }

        /// <summary>
        /// 将对象转换为double
        /// </summary>
        public static double StrToDouble(object expression, double defValue)
        {
            return TypeParse.StrToDouble(expression, defValue);
        }
        #endregion

        #region 回车换行符 与 HTML换行(br)互转
        /// <summary>
        /// 回车换行符 转 Br
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string EnterToBr(string str)
        {
            string str2;
            if (str == null)
            {
                str2 = "";
            }
            else
            {
                str = str.Replace("\r\n", "<br />");
                str = str.Replace("\n", "<br />");
                str2 = str;
            }
            return str2;
        }
        /// <summary>
        /// Br 转 回车换行符
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string BrToEnter(string str)
        {
            string str2;
            if (str == null)
            {
                str2 = "";
            }
            else
            {
                str = str.ToLower().Replace("<br />", "\r\n");
                str = str.ToLower().Replace("<br>", "\r\n");
                str2 = str;
            }
            return str2;
        }
        #endregion

        #region 生成随机码
        /// <summary>
        /// 生成随机码(纯数字),长度自己设置
        /// </summary>
        public static string GetRandomCode(int digit)
        {
            digit--;
            Random rnd = new Random();
            return rnd.Next((int)Math.Pow(10, digit), (int)Math.Pow(10, digit + 1) - 1).ToString();
        }
        /// <summary>
        /// 生成随机码(纯数字),长度自己设置
        /// </summary>
        public static string GetRandomCode(int min, int max)
        {
            Random r = new Random(Guid.NewGuid().GetHashCode());
            return r.Next(min, max + 1).ToString();
        }

        private static char[] constant =   
      {   
        '0','1','2','3','4','5','6','7','8','9',  
        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',   
        'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'   
      };
        /// <summary>
        /// 生成随机码，0-9，a-z,A-Z
        /// </summary>
        /// <param name="Length"></param>
        /// <returns></returns>
        public static string GetRandomString(int Length)
        {
            System.Text.StringBuilder newRandom = new System.Text.StringBuilder(62);
            Random rd = new Random();
            for (int i = 0; i < Length; i++)
            {
                newRandom.Append(constant[rd.Next(62)]);
            }
            return newRandom.ToString();
        }


        #endregion

        #region 获取Cookies
        /// <summary>
        /// 获取Cookies
        /// </summary>
        public static string GetCookies(string cName)
        {
            return GetCookies(cName, "");
        }

        /// <summary>
        /// 获取Cookies
        /// </summary>
        public static string GetCookies(string cName, string domain)
        {
            HttpCookie cookies = HttpContext.Current.Request.Cookies[cName];
            if (cookies == null)
            {
                return "";
            }
            else
            {
                if (!string.IsNullOrEmpty(domain))
                {
                    cookies.Domain = domain;
                }
                return cookies.Value;
            }
        }
        #endregion

        #region 设置Cookies
        /// <summary>
        /// 设置Cookies
        /// </summary>
        /// <param name="cName">Cookies名称</param>
        /// <param name="cValue">Cookies值</param>
        /// <param name="domain">Cookies域</param>
        /// <param name="cExpires">Cookies过期时间</param>
        public static void SetCookies(string cName, string cValue, string domain, DateTime? cExpires)
        {
            HttpCookie cookies = new HttpCookie(cName);
            if (!string.IsNullOrEmpty(domain))
            {
                cookies.Domain = domain;
            }
            if (cExpires is DateTime)
            {
                cookies.Expires = (DateTime)cExpires;
            }
            cookies.Value = cValue;
            HttpContext.Current.Response.Cookies.Add(cookies);
        }
        public static void SetCookies(HttpCookie cookies)
        {
            HttpContext.Current.Response.Cookies.Add(cookies);
        }
        #endregion

        #region 验证URL地址是否存在
        /// <summary>
        /// 验证URL地址是否存在
        /// </summary>
        public static bool ValidUrl(string url)
        {
            WebRequest myWebRequest = WebRequest.Create(url);
            myWebRequest.Timeout = 5000;
            try
            {
                WebResponse myWebResponse = myWebRequest.GetResponse();
                Stream resStream = myWebResponse.GetResponseStream();
                StreamReader sr = new StreamReader(resStream, System.Text.Encoding.Default);

                resStream.Close();
                sr.Close();
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion

        #region DateDiff方法
        public static long DateDiff(DateInterval interval, DateTime startDate, DateTime endDate)
        {
            TimeSpan ts = endDate - startDate;
            switch (interval)
            {
                case DateInterval.Year:
                    return endDate.Year - startDate.Year;
                case DateInterval.Month:
                    return (endDate.Month - startDate.Month) + (12 * (endDate.Year - startDate.Year));
                case DateInterval.Day:
                    return Round(ts.TotalDays);
                case DateInterval.Hour:
                    return Round(ts.TotalHours);
                case DateInterval.Minute:
                    return Round(ts.TotalMinutes);
                case DateInterval.Second:
                    return Round(ts.TotalSeconds);
                case DateInterval.Weekday:
                    return Round(ts.TotalDays / 7.0);
                case DateInterval.Quarter:
                    double d1Quarter = GetQuarter(startDate.Month);
                    double d2Quarter = GetQuarter(endDate.Month);
                    double d1 = d2Quarter - d1Quarter;
                    double d2 = (4 * (endDate.Year - startDate.Year));
                    return Round(d1 + d2);
            }
            return 0;

        }
        public enum DateInterval
        {
            Day,
            Hour,
            Minute,
            Month,
            Quarter,
            Second,
            Weekday,
            Year
        }
        private static int GetQuarter(int nMonth)
        {
            if (nMonth <= 3)
                return 1;
            if (nMonth <= 6)
                return 2;
            if (nMonth <= 9)
                return 3;
            return 4;
        }

        private static long Round(double dVal)
        {
            if (dVal >= 0)
                return (long)Math.Floor(dVal);
            return (long)Math.Ceiling(dVal);
        }
        #endregion

        #region 获取当前网站绝对地址(域名)
        /// <summary>
        /// 获取当前网站绝对地址(域名)
        /// </summary>
        public static string GetAbsolutePath()
        {
            string appPath = string.Format("{0}://{1}{2}",
                HttpContext.Current.Request.Url.Scheme,
                HttpContext.Current.Request.Url.Authority,
                HttpContext.Current.Request.ApplicationPath);
            // 得到绝对路径
            return appPath;
        }
        #endregion

        #region 获取客户端IP
        public static string GetIP()
        {
            string userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (string.IsNullOrEmpty(userHostAddress) || (userHostAddress.ToLower().IndexOf("unknown") > 1))
            {
                userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
            else
            {
                if (userHostAddress.IndexOf(",") > -1)
                {
                    userHostAddress = userHostAddress.Substring(0, userHostAddress.IndexOf(","));
                }
                if (userHostAddress.IndexOf(";") > -1)
                {
                    userHostAddress = userHostAddress.Substring(0, userHostAddress.IndexOf(";"));
                }
            }
            Regex regex = new Regex("[^0-9.]");
            if (((userHostAddress == null) || (userHostAddress.Length == 0)) || regex.IsMatch(userHostAddress))
            {
                userHostAddress = HttpContext.Current.Request.UserHostAddress;
                if (((userHostAddress == null) || (userHostAddress.Length == 0)) || regex.IsMatch(userHostAddress))
                {
                    userHostAddress = "0.0.0.0";
                }
            }
            return userHostAddress;
        }
        #endregion

        #region 对称加密
        /// <summary>
        /// 加密
        /// </summary>
        public static string EncryptDes(string SourceStr)
        {
            string skey = Utils.GetAppSettingsValue("DesKey");
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            Byte[] inputByteArray;
            inputByteArray = Encoding.Default.GetBytes(SourceStr);

            //des.GenerateKey();
            //des.GenerateIV();

            //Convert.ToBase64String
            //set encrypt object and skey
            des.Key = Convert.FromBase64String(skey);
            des.IV = Convert.FromBase64String(skey);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            StreamWriter sw = new StreamWriter(cs);
            sw.Write(SourceStr);
            sw.Flush();
            cs.FlushFinalBlock();
            ms.Flush();
            return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);

        }
        /// <summary>
        /// 解密
        /// </summary>
        public static string DecryptDes(string SourceStr)
        {
            string sKey = Utils.GetAppSettingsValue("DesKey");

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            des.Key = Convert.FromBase64String(sKey);
            des.IV = Convert.FromBase64String(sKey);

            byte[] buffer = Convert.FromBase64String(SourceStr);

            MemoryStream ms = new MemoryStream(buffer);
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read);
            StreamReader sr = new StreamReader(cs);
            return sr.ReadToEnd();


        }

        #endregion

        #region SQL过滤
        public static string SQLFilter(string filterKey)
        {
            //处理了单引
            filterKey = Regex.Replace(filterKey, "'", "’", RegexOptions.IgnoreCase);
            //处理了杠杠
            filterKey = Regex.Replace(filterKey, "'/", "／", RegexOptions.IgnoreCase);
            //处理了关键词
            filterKey = Regex.Replace(filterKey, "%", "％", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(w)(here)", "$1h&#101;re", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(s)(elect)", "$1el&#101;ct", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(i)(nsert)", "$1ns&#101;rt", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(c)(reate)", "$1r&#101;ate", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(d)(rop)", "$1ro&#112;", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(a)(lter)", "$1lt&#101;r", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(d)(elete)", "$1el&#101;te", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(u)(pdate)", "$1p&#100;ate", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(\\s)(or)", "$1o&#114;", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(java)(script)", "$1scri&#112;t", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(j)(script)", "$1scri&#112;t", RegexOptions.IgnoreCase);
            filterKey = Regex.Replace(filterKey, "(vb)(script)", "$1scri&#112;t", RegexOptions.IgnoreCase);
            return filterKey;
        }
        #endregion

        #region 删除HTML标签
        /// <summary>
        /// 删除HTML标签
        /// </summary>
        public static string StripHTML(string strHtml)
        {
            Regex STRIP_HTML = new Regex("<[^>]*>|&[a-zA-Z]+;", RegexOptions.Compiled);
            if (string.IsNullOrEmpty(strHtml))
                return string.Empty;

            return STRIP_HTML.Replace(strHtml, string.Empty);
            //return Regex.Replace(STRIP_HTML.Replace(strHtml, string.Empty), "&[a-zA-Z]+;", "");
        }
        #endregion

        #region URL、HTML编码
        /// <summary>
        /// URL编码
        /// </summary>
        public static string UrlEncode(string obj)
        {
            return UrlEncode(obj, Encoding.GetEncoding("UTF-8"));
        }
        /// <summary>
        /// URL编码 重载
        /// </summary>
        public static string UrlEncode(string obj, Encoding code)
        {
            return HttpUtility.UrlEncode(obj, code);
        }

        /// <summary>
        /// URL解码
        /// </summary>
        public static string UrlDecode(string obj)
        {
            return UrlDecode(obj, Encoding.GetEncoding("UTF-8"));
        }

        /// <summary>
        /// URL解码 重载
        /// </summary>
        public static string UrlDecode(string obj, Encoding code)
        {
            return HttpUtility.UrlDecode(obj, code);
        }

        /// <summary>
        /// HTML编码
        /// </summary>
        public static string HtmlEncode(string obj)
        {
            return HttpContext.Current.Server.HtmlEncode(obj);
        }

        /// <summary>
        /// HTML解码
        /// </summary>
        public static string HtmlDecode(string obj)
        {
            return HttpContext.Current.Server.HtmlDecode(obj);
        }

        #endregion

        #region 提交数据到指定地址
        /// <summary>
        /// 提交数据到指定地址，返回内容。默认Post提交
        /// </summary>
        public static string HostRequest(string uri, string parms, string reqType)
        {
            byte[] data = Encoding.ASCII.GetBytes(parms);
            WebRequest webRequest = WebRequest.Create(uri);
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.Method = reqType;
            webRequest.ContentLength = data.Length;
            Stream stream = webRequest.GetRequestStream();
            stream.Write(data, 0, data.Length);
            stream.Close();
            try
            {
                WebResponse response = webRequest.GetResponse();
                if (response == null)
                    return "";
                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                return sr.ReadToEnd().Trim();
            }
            catch (WebException ex)
            {
                return "Request Error";
            }
        }
        /// <summary>
        /// 提交数据到指定地址，返回内容。默认Post提交
        /// </summary>
        public static string HostRequest(string uri, string parms)
        {
            return HostRequest(uri, parms, "post");
        }
        #endregion

        #region 发送邮件
        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="toMail">目标邮箱</param>
        /// <param name="fromMail">发送者邮箱</param>
        /// <param name="mailBody">邮件内容</param>
        /// <param name="mailSubject">邮件标题</param>
        /// <param name="bcc">是否暗送</param>
        public static bool SendMail(string toMail, string fromMail, string mailBody, string mailSubject, bool bcc)
        {
            return Mail.Send(toMail, fromMail, mailBody, mailSubject, bcc);
        }
        #endregion

        #region 输出JSONP数据
        /// <summary>
        /// 输出JSONP数据
        /// </summary>
        /// <param name="callback">回调函数名</param>
        /// <param name="args">输出数据 (List类型可以直接： list.ToArray<Object>())</param>
        public static string ToJsonp(string callback, object args)
        {
            Type type = args.GetType();

            if (type != null && type.Name.ToLower() == "string")
            {
                /* 已经是字条串的JSON数据 */
                if (string.IsNullOrEmpty(callback))
                    return args.ToString();

                return string.Format("{0}({1})", callback, args);
            }

            if (string.IsNullOrEmpty(callback))
                return JsonConvert.SerializeObject(args);

            return string.Format("{0}({1})", callback, JsonConvert.SerializeObject(args));
        }
        #endregion

        #region 获取星期几
        public static string GetWeek()
        {
            string week = null;
            string dt = DateTime.Today.DayOfWeek.ToString();
            switch (dt)
            {
                case "Monday":
                    week = "星期一";
                    break;
                case "Tuesday":
                    week = "星期二";
                    break;
                case "Wednesday":
                    week = "星期三";
                    break;
                case "Thursday":
                    week = "星期四";
                    break;
                case "Friday":
                    week = "星期五";
                    break;
                case "Saturday":
                    week = "星期六";
                    break;
                case "Sunday":
                    week = "星期日";
                    break;

            }
            return week;
        }
        #endregion

        #region 判断是否本周内
        public static bool ISWeek(string date)
        {
            DateTime dt = Convert.ToDateTime(date);  //指定日期
            int num = Convert.ToInt32(DateTime.Now.DayOfWeek.ToString("d"));
            DateTime start = System.DateTime.Today.AddDays(1 - num);
            TimeSpan ts = dt.Subtract(start);
            if (ts.Days > -1 && ts.Days < 7)

                return true;//本周内
            else
                return false;//非本周

        }
        #endregion

        #region 验证是否手机访问
        public static string ValidateURL()
        {

            string url = HttpContext.Current.Request.Url.ToString();
            //Regex domain = new Regex(@"m\.[\w-]+\.\w{2,5}/");
            Regex domain = new Regex(@"\/mobile\/");
            Match matchName = domain.Match(url);
            return matchName.Value;
            //Content(matchName.Groups[0].Value);

        }
        #endregion

        #region 获取文件扩展名
        /// <summary>
        /// 获取文件扩展名
        /// </summary>
        public static string GetExtension(string fileName)
        {
            return Path.GetExtension(fileName);
        }
        #endregion

        #region Key Value 转为 URL键值字符串，并按字母a~z排序

        public static StringBuilder KeyValueToUrlParams(Dictionary<string, object> dicParames)
        {
            StringBuilder sb = new StringBuilder();
            dicParames = (from entry in dicParames
                          orderby entry.Key ascending
                          select entry).ToDictionary(pair => pair.Key, pair => pair.Value);
            int i = 0;
            foreach (var item in dicParames)
            {
                sb.Append(item.Key + "=" + Utils.UrlEncode(item.Value.ToString()));
                if (i < dicParames.Count)
                {
                    sb.Append("&");
                }
                i++;
            }
            return sb;
        }

        #endregion
    }
}
